<?php
/**
 * Ecart
 *
 * This file is part of Ecart.
 *
 * Ecart is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Ecart is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Ecart.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @category    Ecart
 * @package     Ecart_Catalog
 * @copyright   Copyright 2008-2009 E-Cart LLC
 * @license     GNU Public License V3.0
 */

/**
 *
 * @category    Ecart
 * @package     Ecart_Catalog
 * @subpackage  Box
 * @author      Ecart Core Team <core@ecartcommerce.com>
 */
class Ecart_Catalog_Box_Filters extends Ecart_Core_Box_Abstract
{
    protected $_title = 'Filters';
    protected $_class = 'box-filter';
    public $hurl;

    public function init()
    {
        $this->hurl = Ecart_HumanUri::getInstance();

        $result = array();
        $filters = $this->_getActiveFilters();

        // Get category filters
        /*$catId = $this->hurl->hasParam('cat') ?
            $this->hurl->getParamValue('cat') : Ecart::single('catalog/category')->getRoot()->id;
        $result['category'] = Ecart::single('catalog/category')->find($catId)->current()->getChildItems(false, true);*/

        // Get price filters
        $result['price'] = $this->_getPriceFilters($filters);

        // Get manufacturer filters
        if (!$this->hurl->hasParam('manufacturer')) {
            $result['manufacturer'] = $this->_getManufacturerFilters($filters);
        }

        // Attribute filters
        $result['attributes'] = $this->_getAttributeFilters($filters);

        if ((count($filters) && !$this->hurl->hasParam('cat'))
            || (1 < count($filters) && $this->hurl->hasParam('cat'))) { // we don't show categories in filters

            $this->filters = $result;
            return;
        }

        foreach($result as $filter) {
            if (count($filter)) {
                $this->filters = $result;
                return;
            }
        }

        return false;
    }

    public function hasContent()
    {
        return $this->hasData('filters');
    }

    /**
     * Retrieve array of applied filters
     * @return array
     */
    protected function _getActiveFilters()
    {
        $filters = array();
        if ($this->hurl->hasParam('cat')) {
            $filters['category_ids'] = $this->hurl->getParamValue('cat');
        }

        // Filter by manufacturer
        if ($this->hurl->hasParam('manufacturer')) {
            $filters['manufacturer_ids'] = $this->hurl->getParamValue('manufacturer');
        }

        // by price
        if ($this->hurl->hasParam('price')) {
            list($from, $to) = explode(',', $this->hurl->getParam('price'));
            $filters['price'] = array(
                'from'  => $from,
                'to'    => $to
            );
        }

        // by attributes
        if ($this->hurl->hasParam('attributes')) {
            $filters['attributes'] = $this->hurl->getAttributeIds();
        }

        return $filters;
    }

    /**
     * @param  array $filters
     * @return mixed
     */
    protected function _getManufacturerFilters(array $filters)
    {
        $select = Ecart::single('catalog/product')->select(array(
                'cnt' => 'COUNT(DISTINCT cp.id)'
            ))
            ->joinCategory()
            ->addCommonFilters($filters)
            ->addManufacturer()
            ->group('cpm.id')
            ->order('cpmt.title');

        $manufacturers = $select->fetchAll();

        if (!count($manufacturers)) {
            return null;
        }

        return $manufacturers;
    }

    /**
     * Возвращает список фильтрова для атрибутов
     *
     * @return mixed
     */
    protected function _getAttributeFilters(array $filters)
    {
        $select = Ecart::single('catalog/product')->select(array(
                'cnt' => 'COUNT(DISTINCT cp.id)'
            ))
            ->joinCategory()
            ->addCommonFilters($filters)
            ->joinInner('catalog_product_attribute',
                'cp.id = cpa.product_id',
                array(
                    'option_id',
                    'option_value_id'
                ))
            ->join('catalog_product_option', 'cpa.option_id = cpo.id') 
            ->join('catalog_product_option_text',
                'cpa.option_id = cpot.option_id',
                array(
                    'option_name' => 'name'
                ))
            ->joinInner('catalog_product_option_value_text',
                'cpa.option_value_id = cpovt.option_value_id',
                array(
                    'value_name' => 'name'
                ))
            ->where('cpo.filterable = 1')
            ->where('cpot.language_id = ?', Ecart_Locale::getLanguageId())
            ->where('cpovt.language_id = ?', Ecart_Locale::getLanguageId())
            ->group(array('cpa.option_id', 'cpa.option_value_id'));

        if (isset($filters['attributes']) && count($filters['attributes'])) {
            $select->where('cpa.option_id NOT IN (?)', array_keys($filters['attributes']));
        }

        $attributes = $select->fetchAll();
        if (!count($attributes)) {
            return null;
        }

        $filters = array();
        foreach ($attributes as $attribute) {
            if (!isset($filters[$attribute['option_id']])) {
                $filters[$attribute['option_id']] = array();
            }

            $filters[$attribute['option_id']][] = $attribute;
        }
        return $filters;
    }

    /**
     * Return price filters
     *
     * @return mixed
     */
    protected function _getPriceFilters(array $filters)
    {
        $select = Ecart::single('catalog/product')->select();
        $select->from('catalog_product', array(
                'cnt'       => 'COUNT(cp.price)',
                'price_max' => 'MAX(cp.price)',
                'price_min' => 'MIN(cp.price)'
            ))
            ->joinCategory()
            ->addCommonFilters($filters);

        $row = $select->fetchRow();

        if (!$row['cnt']) {
            return null;
        }

        //Return rounded number, example: 80->10, 120->100, 895->100, 1024->1000
        $roundTo = pow(10, strlen((string) floor($row['price_max'] - $row['price_min'])) - 1);
        $select->reset();
        $select->from('catalog_product', array(
                'cnt'         => 'COUNT(DISTINCT cp.id)',
                'price_group' => new Zend_Db_Expr("floor(cp.price / $roundTo) * $roundTo")
            ))
            ->joinCategory()
            ->addCommonFilters($filters)
            ->group('price_group')
            ->order('cp.price');

        $priceGroups = $select->fetchAll();

        if (count($priceGroups) < 2) {
            return null;
        }

        return array(
            'roundTo' => $roundTo,
            'groups'  => $priceGroups
        );
    }
}